package com.gitee.huxing.course.netty.gateway.factory;

import com.gitee.huxing.course.netty.gateway.router.NettyRouter;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @Description: 抽象业务逻辑处理
 * @ProjectName: JavaCourse
 * @Package: com.gitee.huxing.course.netty.gateway.factory
 * @ClassName: BusinessFactory
 * @Author: huxing
 * @DateTime: 2021-08-21 下午3:05
 */
@Slf4j
public abstract class AbstractBusinessFactory<T, E, N> implements BusinessService {

    /** 处理请求对象 **/
    private T object;

    /** 渠道 **/
    private E channel;

    /** 过滤器 **/
    private List<N> filters;

    /** 路由 **/
    private NettyRouter router;

    @Override
    public void process(Object request, Object channel) {
        try {
            // 设置处理渠道
            this.channel = (E)channel;
            // 过滤处理
            Object body = this.processFilter((T)request, filters);
            // 是否处理路由
            this.processRouter((T)body);
            // 转发处理
            this.send((T)body, (E)channel);
        } catch (Exception ex){
            ex.printStackTrace();
            log.info("消息处理出现异常: {}", ex.getMessage());
            this.err((T)request, (E)channel, "网关消息处理异常");
        }
    }

    /**
     * @Description: 链路过滤处理
     * @Author: huxing
     * @param request   请求记录
     * @param filters   过滤器
     * @Date: 2021/8/21 下午3:13
     **/
    public abstract T processFilter(T request, List<N> filters);


    /**
     * @Description:    路由处理
     * @Author: huxing
     * @param request   请求消息
     * @Date: 2021/8/21 下午3:15
     **/
    public abstract void processRouter(T request);

    /**
     * @Description:    消息转发
     * @Author: huxing
     * @param object    消息对象
     * @param channel   发送渠道
     * @Date: 2021/8/21 下午3:32
     **/
    public abstract void send(T object, E channel);

    /**
     * @Description: 链路异常处理
     * @Author: huxing
     * @param object    消息对象
     * @param channel   处理渠道
     * @param err       错误消息
     * @Date: 2021/8/21 下午4:04
     **/
    public abstract void err(T object, E channel, String err);

    public List<N> getFilters() {
        return filters;
    }

    public void setFilters(List<N> filters) {
        this.filters = filters;
    }

    public NettyRouter getRouter() {
        return router;
    }

    public void setRouter(NettyRouter router) {
        this.router = router;
    }

    public E getChannel() {
        return channel;
    }

    public T getObject() {
        return object;
    }

    public void setObject(T object) {
        this.object = object;
    }

    public void setChannel(E channel) {
        this.channel = channel;
    }
}
